package com.formula.distribution.lock.core;

import com.formula.distribution.lock.annotation.Lock;
import com.formula.distribution.lock.config.LockConfig;
import com.formula.distribution.lock.entity.LockInfo;
import lombok.Data;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @author:bo
 * @email:
 * @date 2018/12/25
 * @introduce
 **/
public class LockInfoProvider {


    public static final String LOCK_NAME_PREFIX = "lock";
    public static final String LOCK_NAME_SEPARATOR = ".";

    @Autowired
    private LockConfig lockConfig;


    @Autowired
    BusinessKeyProvider businessKeyProvider;


    public LockInfo get(ProceedingJoinPoint point, Lock lock) {

        MethodSignature methodSignature = (MethodSignature) point.getSignature();
        String keyName = businessKeyProvider.getKeyName(point, lock);
        String lockName = LOCK_NAME_PREFIX + LOCK_NAME_SEPARATOR + getName(lock.name(), methodSignature) + keyName;
        long waitTime = getWaitTime(lock);
        long leaseTime = getLeaseTime(lock);
        return new LockInfo(lock.Lockype(), lockName, waitTime, leaseTime);
    }


    private String getName(String annotationNames, MethodSignature methodSignature) {

        if (annotationNames.isEmpty()) {
            return String.format("%s.%s", methodSignature.getDeclaringTypeName(), methodSignature.getMethod().getName());
        } else {
            return annotationNames;
        }
    }


    private long getWaitTime(Lock lock) {
        return lock.waitTime() == Long.MIN_VALUE ? lockConfig.getWaitTime() : lock.waitTime();
    }


    private long getLeaseTime(Lock lock) {
        return lock.leaseTime() == Long.MIN_VALUE ? lockConfig.getLeaseTime() : lock.leaseTime();
    }

}
